package com.ggk911.pharmacy_system.util;

import com.ggk911.pharmacy_system.entity.User;
import com.ggk911.pharmacy_system.service.impl.UserServiceImpl;
import io.jsonwebtoken.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;

/**
 * JWT工具类
 *
 * @author ggk-911
 * @version 1.0 2023/2/24 9:23
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class JWTUtil {
    private final UserServiceImpl userService;

    /**
     * 生成Token
     *
     * @param user Token中要保存的对象
     * @return 生成的字符串
     */
    public String createToken(User user) {
        //1.有效时间.
        long now = System.currentTimeMillis();
        //到期时间
        long expTime = now + 1 * 24 * 3600 * 1000;

        //2.负载信息
        HashMap<String, Object> map = new HashMap();
        map.put("UserId", user.getUserId());
        map.put("UserName", user.getUserName());
        map.put("UserPwd", user.getUserPwd());
        map.put("RoleId", user.getRoleId());

        //3.构造Token对象
        JwtBuilder builder = Jwts.builder();
        builder.setClaims(map) //信息
                .setIssuer("com.ggk911") //签发人
                .setIssuedAt(new Date(now)) //签发时间
                .setExpiration(new Date(expTime)) //到期时间
                .signWith(SignatureAlgorithm.HS256, "GGK911"); //算法和签名
        return builder.compact();
    }

    /**
     * 解析并验证Token
     *
     * @param token 要解析的Token
     * @return 解析后的对象
     */
    public RestResult verifyAndConvertToken(String token) {
        Claims body = null; //获取解析后的字符串
        try {
            body = Jwts.parser() //解析Token对象
                    .setSigningKey("GGK9911") //提供签名
                    .parseClaimsJws(token) //提供Token
                    .getBody();
            String userName = (String) body.get("UserName");
            String userPwd = (String) body.get("UserPwd");
            log.info("token验证：" + userName + "|" + userPwd);
            //验证Token是否被替换
            if (userService.login(userName, userPwd) == null)
                return RestResult.error("token解析验证失败");
        } catch (ExpiredJwtException e) {
            log.error(String.valueOf(e));
            return RestResult.error("登录过期");
        } catch (Exception e) {
            log.error(String.valueOf(e));
            return RestResult.error("token验证失败");
        }

        return RestResult.ok("token验证成功", body);
    }
}
